//
//  MyCLController.h
//  Aeropuertos
//
//  Created by sid on 01/04/10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "LocateMeController.h"

// This is a singleton class, see below
static LocateMeController *sharedCLDelegate = nil;

@implementation LocateMeController

@synthesize delegate, locationManager, updating;

- (id)init 
{
	self = [super init];
	if (self != nil) 
	{
		self.locationManager = [[[CLLocationManager alloc] init] autorelease];
		self.locationManager.delegate = self; // Tells the location manager to send updates to this object
		self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
		self.locationManager.distanceFilter = kCLDistanceFilterNone;
	}
	
	return self;
}

- (void)startUpdatingLocation 
{
	self.updating = YES;
	[self.locationManager startUpdatingLocation];
}

-(void)stopUpdatingLocation 
{
	self.updating = NO;
	[self.locationManager stopUpdatingLocation];
}

// Called when the location is updated
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
	// Negative accuracy means an invalid or unavailable measurement
	if (signbit(newLocation.horizontalAccuracy)) 
	{
		return;
	}
	
	// If location timestamp was ages ago, it's a cached one; ignore it
	NSTimeInterval howRecent = [newLocation.timestamp timeIntervalSinceNow];
	
	if (abs(howRecent) > 5.0) 
	{
		return;
	}
	
	[self.delegate newLocationUpdate:newLocation];
}


// Called when there is an error getting the location
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
	NSMutableString *errorString = [[[NSMutableString alloc] init] autorelease];
	
	if ([error domain] == kCLErrorDomain) 
	{
		
		// We handle CoreLocation-related errors here
		
		switch ([error code]) 
		{
				// This error code is usually returned whenever user taps "Don't Allow" in response to
				// being told your app wants to access the current location. Once this happens, you cannot
				// attempt to get the location again until the app has quit and relaunched.
				//
				// "Don't Allow" on two successive app launches is the same as saying "never allow". The user
				// can reset this for all apps by going to Settings > General > Reset > Reset Location Warnings.
				//
			case kCLErrorDenied:
				[self stopUpdatingLocation];
				[self.delegate newLocationError:@"Needs your location to know where your problem is."];
				break;
				
				// This error code is usually returned whenever the device has no data or WiFi connectivity,
				// or when the location cannot be determined for some other reason.
				//
				// CoreLocation will keep trying, so you can keep waiting, or prompt the user.
				//
			case kCLErrorLocationUnknown:
				[self stopUpdatingLocation];
				[errorString appendFormat:@"%@\n", NSLocalizedString(@"LocationUnknown", nil)];
				break;
				
				// We shouldn't ever get an unknown error code, but just in case...
				//
			default:
				[self stopUpdatingLocation];
				[errorString appendFormat:@"%@ %d\n", NSLocalizedString(@"GenericLocationError", nil), [error code]];
				break;
		}
	}
	else 
	{
		// We handle all non-CoreLocation errors here
		// (we depend on localizedDescription for localization)
		[errorString appendFormat:@"Error domain: \"%@\"  Error code: %d\n", [error domain], [error code]];
		[errorString appendFormat:@"Description: \"%@\"\n", [error localizedDescription]];
	}
	
	self.updating = NO;
	
	// Send the update to our delegate
	[self.delegate newLocationError:errorString];
}

#pragma mark ---- singleton object methods ----

// See "Creating a Singleton Instance" in the Cocoa Fundamentals Guide for more info

+ (LocateMeController *)sharedInstance 
{
    @synchronized(self) 
	{
        if (sharedCLDelegate == nil) 
		{
            [[self alloc] init]; // assignment not done here
        }
    }
	
    return sharedCLDelegate;
}

+ (id)allocWithZone:(NSZone *)zone
{
    @synchronized(self)
	{
        if (sharedCLDelegate == nil) 
		{
            sharedCLDelegate = [super allocWithZone:zone];
            return sharedCLDelegate;  // assignment and return on first allocation
        }
    }
	
    return nil; // on subsequent allocation attempts return nil
}

- (id)copyWithZone:(NSZone *)zone
{
    return self;
}

- (id)retain 
{
    return self;
}

- (unsigned)retainCount
{
    return UINT_MAX;  // denotes an object that cannot be released
}

- (void)release 
{
    //do nothing
	[self.locationManager release];
}

- (id)autorelease 
{
    return self;
}

@end